/*
 *  Copyright:  (C) 2018 LingYun IoT System Studio
 *              All rights reserved.
 *
 *  File name:  fork_exec.c
 *Description:  Get ip address of eth0,without using "ifconfig".
 *
 *    Version:  1.1
 *     Author:  Guo Wenxue <guowenxue@gmail.com>
 *		        Copied by Zhu Tianyin <zhuty_cn@163.com>
 *  ChangeLog:  1.0  Release initial version in 2018.
 *              1.1  Copy and change some details on "01/11/2021".
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

#define TMP_FILE "/tmp/.ifconfig.log" //This file is not existing,it's what we creat.

int main(int argc, char **argv)
{
	pid_t pid;
	int fd;
	char buf[1024];
	int rv;
	char *ptr;
	FILE *fp;
	char *ip_start;
	char *ip_end;
	char ipaddr[16];

	//Father process opens this file,and child process will inherit "fd".
	//Then father process and child process can operate the same file through their own "fd".
	if((fd=open(TMP_FILE, O_RDWR|O_CREAT|O_TRUNC, 0644))<0)
	{
		printf("Redirect standard output to file failure: %s\n", strerror(errno));
		return -1;
	}
	//Father process starts create child process.
	pid = fork();
	if(pid<0)
	{
		printf("Fork() create child process failure: %s\n", strerror(errno));
		return -1;
	}
	else if(pid == 0)
	{
		printf("Child process start excute ifconfig program\n");
		dup2(fd, STDOUT_FILENO);
		execl("/sbin/ifconfig", "ifconfig", "eth0", NULL);
		printf("Child process excute another program, will not return here.Return here means execl() error\n");
		return -1;
	}
	else sleep(3); //Father process waits 3 seconds,and let child process operate first.
	//Because of execl(),child process will lose text segment of father process.
	//Only father process will continue executing following code.
	memset(buf, 0, sizeof(buf));
	lseek(fd, 0, SEEK_SET);  //Important.
	rv = read(fd, buf, sizeof(buf));
	printf("Read %d bytes data after lseek: %s\n", rv, buf);
	//In order to read the contents of the file line by line,we use fdopen() to convert "fd" to file stream "fp".
	fp = fdopen(fd, "r");
	fseek(fp, 0, SEEK_SET);
	while(fgets(buf, sizeof(buf),fp))
	{
		if(strstr(buf, "netmask"))
		{
			ptr = strstr(buf, "inet");
			if(!ptr)
			{
				break;
			}
			ptr += strlen("inet");
			//Skip "\0" or "TAB".
			while(isblank(*ptr))
				ptr ++;
			ip_start = ptr;
			while(!isblank(*ptr))
				ptr ++;
			ip_end = ptr;
			//Copy ip address.
			memset(ipaddr, 0, sizeof(ipaddr));
			memcpy(ipaddr, ip_start, ip_end-ip_start);
			break;
		}
	}
	printf("Parser and get ip address: %s\n", ipaddr);
	fclose(fp);
	unlink(TMP_FILE);
	return 0;
}	
